home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 298_01 / demo.c < prev    next >
C/C++ Source or Header  |  1987-06-05  |  10KB  |  374 lines

  1. /* PC Curses. (C) Copyright 1987 Jeffrey S. Dean.  All Rights Reserved. */
  2.  
  3. /* demo - simple program to demonstrate curses
  4.  *
  5.  *    The purpose of this program is to demonstrate PC Curses.
  6.  *    It provides a working example of what PC Curses looks like
  7.  *    when running; it also provides examples of how to write code
  8.  *    using the PC Curses package (for those who might not be
  9.  *    familiar with it).
  10.  *
  11.  *    brief outline:
  12.  *    reads in a data file, containing short paragraphs separated
  13.  *    by formfeeds; there can be no more than COUNT paragraphs.
  14.  *    each paragraph is put in a window, and then the user hits
  15.  *    <return> to sequence through the windows.
  16.  *
  17.  *    functions:
  18.  *    main
  19.  *    fillwin     - fills window with data from a file
  20.  *    changemode     - toggles between bios and direct screen updates
  21.  *    changerefresh     - toggles between wrefresh() and wnoutrefresh()
  22.  *    help         - displays a help screen
  23.  *    message        - places message in prompt window
  24.  */
  25.  
  26. /* the standard include file for curses */
  27. #include <curses.h>
  28. /* if working on unix, use this special include file
  29.  * for extended or non-standard PC Curses things
  30.  */
  31. #ifdef unix
  32. #include "unix.h"
  33. #endif
  34.  
  35. /* the data file */
  36. #define DEMODATA "demo.dat"
  37. /* the help file */
  38. #define HELPFILE "demo.hlp"
  39.  
  40. /* maximum of windows */
  41. #define COUNT 10
  42. /* size of each window */
  43. #define NUMCOLS 60
  44. #define NUMROWS 11
  45.  
  46. /* an array of window pointers */
  47. WINDOW *winlist[COUNT];
  48. /* the last window in winlist */
  49. int last;
  50.  
  51. /* coordinates of first window */
  52. #define YFIRST 2
  53. #define XFIRST 2
  54.  
  55. /* flag to use wnoutrefresh instead of wrefresh */
  56. int norefresh = 0;
  57.  
  58. /* window for the prompt message */
  59. WINDOW *promptwin;
  60. /* the prompt message */
  61. char prompt[] = 
  62.           "  <RETURN> for next, <BACKSPACE> for previous, F1 for help  \n";
  63.  
  64. main()
  65. {
  66.  int i, j, cmd;
  67.  FILE *demofile;
  68.  
  69.     /** standard curses initialization **/
  70.     if( ERR == initscr() ) {
  71.         fprintf(stderr, "cannot initialize screen!\n");
  72.         exit(1);
  73.     }
  74.     /* set up function key translation */
  75.     keypad(stdscr, TRUE);
  76.     /* raw mode means we get to handle ^C etc. */
  77.     raw();
  78.     /* do not automatically echo user's input */
  79.     noecho();
  80.     /* nonl() is mainly for Unix compatibility */
  81.     nonl();
  82.  
  83.     /* set up the prompt window */
  84.     if( NULL == (promptwin = newwin(1, sizeof(prompt), LINES-1, 10)) ) {
  85.         fprintf(stderr, "cannot open prompt window\n");
  86.         endwin();
  87.         exit(1);
  88.     }
  89.     else wstandout(promptwin);
  90.     message(prompt);
  91.     /* setting leaveok turns off the cursor in the window */
  92.     leaveok(promptwin, TRUE);
  93.     leaveok(curscr, TRUE);
  94.     
  95.     /* set up the demo data file */
  96.     demofile = fopen(DEMODATA, "r");
  97.     if( demofile == NULL ) {
  98.          perror(DEMODATA);
  99.          exit(1);
  100.     }
  101.     /* we now create and fill up windows from the demo data file */
  102.     for( i = 0; i < COUNT; i++ ) {
  103.         /* allocate a new window */
  104.         winlist[i] = newwin(NUMROWS, NUMCOLS, 
  105.                     YFIRST + i, XFIRST + 2*i);
  106.         if( winlist[i] == NULL ) {
  107.             fprintf(stderr, "cannot open window #%d\n", i);
  108.             endwin();
  109.             exit(1);
  110.         }
  111.         /* draw a double box around it */
  112.         box(winlist[i], D_VERT, D_HOR);
  113.         /* and break if no more data */
  114.         if( fillwin(demofile, winlist[i]) == 0 ) break;
  115.     }
  116.     fclose(demofile);
  117.     
  118.     last = i-1;
  119.     /* up to this point, windows have been filled but
  120.      *  none have been displayed.  now display them,
  121.      *  layered on top of each other, starting with
  122.      *  the last and working up to the first.
  123.      *
  124.      * Note that refresh here is more complicated than it will
  125.      *  normally be in an application, since we handle two kinds
  126.      *  of refreshing (termcap-style and terminfo-style), based
  127.      *  on the norefresh flag.
  128.      */
  129.     for( i = last; i >= 0; i-- ) {
  130.         if( norefresh ) wnoutrefresh(winlist[i]);
  131.         else wrefresh(winlist[i]);
  132.     }
  133.     if( norefresh ) doupdate();
  134.     /* sequence through the windows */
  135.     for( i = 0; i <= last; ) {
  136.         /* draw highlighted box around the top window
  137.          *  note that we are boxing with both single and horizontal
  138.          *  lines; box() is smart enough to choose the right
  139.          *  corner characters.
  140.          */
  141.         box(winlist[i], A_REVERSE|S_VERT, A_REVERSE|D_HOR);
  142.  
  143.         /* refresh current window (pop it to the top) */
  144.         if( norefresh ) wnoutrefresh(winlist[i]);
  145.         else wrefresh(winlist[i]);
  146.         
  147.         /* display whatever is on the prompt line */
  148.         wrefresh(promptwin);
  149.         /* and wait for user input */
  150.         cmd = getch();
  151.         /* restore normal (unhighlighted) box */
  152.         box(winlist[i], S_VERT, D_HOR);
  153.         if( norefresh ) wnoutrefresh(winlist[i]);
  154.         else wrefresh(winlist[i]);
  155.  
  156.         /* process user's command
  157.          *  this is an example of a typical curses command loop
  158.          */
  159.         switch(cmd) {
  160.             case KEY_UP:
  161.             case KEY_LEFT:
  162.             case '\b':    /* backspace goes back one window */
  163.                 if( i > 0 ) i--;
  164.                 break;
  165.             case KEY_DOWN:
  166.             case KEY_RIGHT:
  167.             case '\r':    /* return goes forward one window */
  168.             case '\n':
  169.                 i++;
  170.                 break;
  171.             case '\002':    /* control-b toggle bios updating */
  172.                 changemode();
  173.                 break;
  174.             case '\003':    /* control-c aborts */
  175.                 endwin();
  176.                 exit(1);
  177.             case '\007':    /* control-g flashes */
  178.                 beep();
  179.                 flash();
  180.                 break;
  181.             case '\f':    /* formfeed redisplays the screen */
  182.                 /* fix the prompt line */
  183.                  message(prompt);
  184.                 /* clear the screen */
  185.                 wclear(curscr);
  186.                 /* redisplay to get to initial state */
  187.                 for( j = last; j >= 0; j-- ) {
  188.                     touchwin(winlist[j]);
  189.                     if( norefresh )
  190.                         wnoutrefresh(winlist[j]);
  191.                     else     wrefresh(winlist[j]);
  192.                 }
  193.                 /* move back down to current window */
  194.                 for( j = 0; j < i; j++ ) {
  195.                     touchwin(winlist[j]);
  196.                     if( norefresh )
  197.                         wnoutrefresh(winlist[j]);
  198.                     else wrefresh(winlist[j]);
  199.                 }
  200.                 break;
  201.             case '\027':    /* control-w toggles refresh mode */
  202.                 changerefresh();
  203.                 break;
  204.             case KEY_F(1):
  205.                 help(HELPFILE);
  206.                 break;
  207.             default:
  208.                  message(prompt);
  209.                 break;
  210.             }
  211.     }
  212.     /** normal procedure for exiting curses **/
  213.     /* clear the screen */
  214.     clear();
  215.     refresh();
  216.     /* tell curses we are done */
  217.     endwin();
  218.     exit(0);
  219. }
  220.  
  221. int scradr = T_BIOS;
  222.  
  223. /* changemode - change screen update mode */
  224. changemode()
  225. {
  226.  char buf[80];
  227.  
  228.     if( scradr == T_BIOS ) {
  229.         sprintf(buf, "Screen update method: DIRECT (at 0x%4.4X)",
  230.                 scradr = pc_uptype(T_DIRECT) );
  231.     }
  232.     else {
  233.         scradr = pc_uptype(T_BIOS);
  234.         strcpy(buf, " Screen update method: BIOS");
  235.     }
  236.     message(buf);
  237. }
  238.  
  239. /* changerefresh - change refresh method
  240.  *
  241.  *    old style of refresh is to use wrefresh;
  242.  *    new style of refresh is to use wnoutrefresh, then
  243.  *    doupdate() after all change have been made, resulting
  244.  *    in just one screen update.
  245.  */
  246. changerefresh()
  247. {
  248.     norefresh = !norefresh;
  249.     if( norefresh )
  250.         message("Using new style (wnoutrefresh/doupdate) updating");
  251.     else
  252.         message("Using old style (wrefresh) updating");
  253. }
  254.  
  255. /* message - display message in the prompt window */
  256. message(str)
  257.  char *str;
  258. {
  259.     wmove(promptwin, 0, 0);
  260.     wclrtoeol(promptwin);
  261.     wmove(promptwin, 0, 1);
  262.     waddstr(promptwin, str);
  263. }
  264.  
  265. /** the following two functions, help() and fillwin(), are general
  266.  *  purpose routines.  help displays a help window; fillwin fills
  267.  *  a window from a file, interpreting control characters as attributes.
  268.  *
  269.  *  Usage:
  270.  *    help(filename)
  271.  *      char *filename;
  272.  *    returns OK if successful, ERR otherwise.
  273.  *    In this version, the filename is only used the first time
  274.  *    through; subsequent calls just use the same data.
  275.  *    An error return is possible only on the first call, and
  276.  *    indicates a problem with the help file or a memory shortage.
  277.  *
  278.  *    The help window disappears when any key is pressed.
  279.  *
  280.  *    fillwin(f, win);
  281.  *     FILE *f; WINDOW *win;
  282.  *    returns 0 on EOF, 1 otherwise
  283.  *    Reads data until a formfeed, puts data into window.  Several
  284.  *    control characters are allowed; their occurrence in the file
  285.  *    causes fillwin to modify attributes.  The valid characters are:
  286.  *        ^B - bold
  287.  *        ^F - flash
  288.  *        ^N - normal
  289.  *        ^R - reverse
  290.  *        ^U - underline
  291.  */
  292.  
  293. help(file)
  294.  char *file;
  295. {
  296.  static WINDOW *helpwin = NULL, *shadow;
  297.  static int stat = OK;
  298.  FILE *f;
  299.  
  300.     if( stat == ERR ) return(ERR);
  301.     if( helpwin == NULL ) {